// ALERT: 此代码中的队列
//  1. 使用的是循环队列（牺牲一个存储空间）；
//  2. 队头指针和队尾指针初值均认为是0

#include <stdio.h>

#define MaxSize 5

typedef int ElemType;


typedef struct {
	ElemType data[MaxSize];
	int front, rear;
} SqQueue;


// FUNCTION: 初始化队列
void InitQueue(SqQueue &Q) {
	Q.rear = Q.front = 0;
}


// FUNCTION: 判队列空
bool isEmpty(SqQueue Q) {
	if (Q.rear == Q.front) {
		return true;
	} else {
		return false;
	}
}


// FUNCTION: 判队列满
bool isFull(SqQueue Q) {
	if ((Q.rear + 1) % MaxSize == Q.front) {
		return true;
	} else {
		return false;
	}
}


// FUNCTION: 入队
// @param: ElemType代表出栈元素的值
bool EnQueue(SqQueue &Q, ElemType val) {
	if (isFull(Q)) {
		return false;
	}

	Q.data[Q.rear] = val;
	Q.rear = (Q.rear + 1) % MaxSize;

	return true;
}


// FUNCTION: 出队
// @param: val代表出队元素的值
bool DeQueue(SqQueue &Q, ElemType &val) {
	// NOTE: 出队合法性检查
	if (isEmpty(Q)) {
		return false;
	}

	val = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;

	return true;
}


int main() {
	setbuf(stdout, NULL);


	// NOTE: Variable declaration
	// STEP: 定义栈结构体类型
	SqQueue Q;

	// STEP: 定义变量，ElemType类型，用于存放弹队元素值
	ElemType value;


	// NOTE: 初始化队
	printf("Queue initiating...\n");
	InitQueue(Q);
	printf("Initiation finished.\n");

	printf("Whether queue is empty, or not?\n");
	if (isEmpty(Q)) {
		printf("Queue is empty.\n");
	} else {
		printf("Queue is not empty yet!\n");
	}


	// NOTE: 数据入队
	if (EnQueue(Q, 3)) {
		printf("EnQueue success!\n");
	} else {
		printf("EnQueue failed!\n");
	}

	if (EnQueue(Q, 4)) {
		printf("EnQueue success!\n");
	} else {
		printf("EnQueue failed!\n");
	}

	if (EnQueue(Q, 5)) {
		printf("EnQueue success!\n");
	} else {
		printf("EnQueue failed!\n");
	}

	if (EnQueue(Q, 6)) {
		printf("EnQueue success!\n");
	} else {
		printf("EnQueue failed!\n");
	}

	if (EnQueue(Q, 7)) {
		printf("EnQueue success!\n");
	} else {
		printf("EnQueue failed!\n");
	}


	// NOTE: 数据出队
	printf("DeQueue the top element of queue...\n");
	if (DeQueue(Q, value)) {
		printf("DeQueue success. Its value is %d\n", value);
	} else {
		printf("出队失败\n");
	}

	if (DeQueue(Q, value)) {
		printf("DeQueue success. Its value is %d\n", value);
	} else {
		printf("出队失败\n");
	}


	// NOTE: 其他操作
	if (EnQueue(Q, 8)) {
		printf("入队成功\n");
	} else {
		printf("入队失败\n");
	}


	return 0;
}